package com.ac.scum.log.task.face.log.counsumer.stages.gamplay;

import com.ac.common.core.id.SnowflakeIdGenerator;
import com.ac.scum.log.bean.Player;
import com.ac.scum.log.bean.PlayerAlarm;
import com.ac.scum.log.bean.ServerFTPLogFlag;
import com.ac.scum.log.task.face.log.counsumer.LogConsumer;
import com.ac.scum.log.task.face.log.counsumer.PlayerAlarmInterface;
import com.ac.scum.log.task.face.log.counsumer.stages.GameplayLogConsumer;
import com.ac.scum.log.task.mapper.log.ServerFTPLogFlagMapper;
import com.ac.scum.log.task.utils.map.GameMapZoneUtil;
import com.ac.scum.log.task.utils.queue.FTPQueueItem;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@AllArgsConstructor
public class FlagConsumer implements PlayerAlarmInterface {
    private final GameMapZoneUtil gameMapZoneUtil;
    private final SnowflakeIdGenerator snowflakeIdGenerator;
    private final ServerFTPLogFlagMapper serverFTPLogFlagMapper;

    public void flagConsumer(List<LogConsumer.GameLogLine> lines, FTPQueueItem ftpQueueItem, GameplayLogConsumer gameplayLogConsumer) {
        try {
            String changePattern = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Overtaken \\(Left squad/Promoted\\)\\. New owner: (\\d+) \\((\\d+), (.+?)\\)\\. Old owner: (\\d+) \\((\\d+), (.+?)\\)\\. FlagId: (\\d+)\\. Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+)";
            String destroyedOrCreatePattern = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] (Created|Destroyed).+?FlagId: (\\d+).+?Owner:.+?(.+?) \\((.+?), (.+?)\\).+?Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+)";
            String abandonedPattern = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Overtake canceled\\. User: (.*?)\\s*\\((\\d+), (\\d+)\\)\\. Owner: (N/A|\\d+)\\s*\\((\\d+), (.*?)\\)\\. FlagId: (\\d+)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)";
            String abandonedPattern2 = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Abandoned on overtake\\. Overtaker: (\\d+) \\((\\d+), (.*?)\\)\\. Old owner: (NULL|\\d+)?,? \\((-?\\d+), (.*?)\\)\\. FlagId: (\\d+)\\. Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+)";
            String abandonedPattern3 = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Overtake canceled\\. User: (.+?) \\((\\d+), (\\d+)\\)\\. Owner: (NULL|\\d+), \\((\\d+), (NULL|[^\\)]+)\\)\\. FlagId: (\\d+)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)";
            String overtakeStartedPattern = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Overtake started\\. User: (.*?) \\((\\d+), (\\d+)\\) Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)\\. Owner: (N/A|\\d+ \\(\\d+, [^)]+\\))\\. FlagId: (\\d+)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)";
            String overtakeStartedPattern2 = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Overtake started\\. User: ([^ ]+) \\((\\d+), (\\d+)\\) Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)\\. Owner: (NULL|\\d+), \\((\\d+), (NULL|[^\\)]+)\\)\\. FlagId: (\\d+)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)";
            String overtakeSuccessPattern = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Overtaken\\. New owner: (\\d+) \\((\\d+), (.+?)\\)\\. Old owner: (NULL|\\d+), \\((-?\\d+), (NULL|.+?)\\)\\. FlagId: (\\d+)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)";
            Pattern overtakeSuccessPattern2 = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogBaseBuilding\\] \\[Flag\\] Overtaken\\. New owner: (\\d+) \\((\\d+), ([^\\)]+)\\)\\. Old owner: (\\d+) \\((\\d+), ([^\\)]+)\\)\\. FlagId: (\\d+)\\. Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+)");
            List<ServerFTPLogFlag> flags = Lists.newArrayList();
            for (LogConsumer.GameLogLine line : lines) {
                String lineContext = line.getLineContext();

                Pattern changeRegex = Pattern.compile(changePattern);
                Matcher changeMatcher = changeRegex.matcher(lineContext);

                Pattern createOrDestroyedRegex = Pattern.compile(destroyedOrCreatePattern);
                Matcher createOrDestroyedMatcher = createOrDestroyedRegex.matcher(lineContext);

                Pattern abandonedRegex = Pattern.compile(abandonedPattern);
                Matcher abandonedMatcher = abandonedRegex.matcher(lineContext);

                Pattern abandonedRegex2 = Pattern.compile(abandonedPattern2);
                Matcher abandonedMatcher2 = abandonedRegex2.matcher(lineContext);

                Pattern abandonedRegex3 = Pattern.compile(abandonedPattern3);
                Matcher abandonedMatcher3 = abandonedRegex3.matcher(lineContext);

                Pattern overtakeStartedRegex = Pattern.compile(overtakeStartedPattern);
                Matcher overtakeStartedMatcher = overtakeStartedRegex.matcher(lineContext);

                Pattern overtakeStartedRegex2 = Pattern.compile(overtakeStartedPattern2);
                Matcher overtakeStartedMatcher2 = overtakeStartedRegex2.matcher(lineContext);

                Pattern overtakeSuccessRegex = Pattern.compile(overtakeSuccessPattern);
                Matcher overtakeSuccessMatcher = overtakeSuccessRegex.matcher(lineContext);

                Matcher overtakeSuccessMatcher2 = overtakeSuccessPattern2.matcher(lineContext);

                // 0 更改所有者 1创建 2销毁 3取消创建 4取消占领 5开始占领 6占领成功
                int action = 9;
                String serverTime = "";
                String newOwnerSteamID = "";
                String newOwnerPlayerName = "";
                String oldOwnerSteamID = "";
                String oldOwnerPlayerName = "";
                String flagId = "";
                String locationX = "";
                String locationY = "";
                String locationZ = "";
                String coordinateX = "";
                String coordinateY = "";
                String coordinateZ = "";
                if (changeMatcher.find()) {
                    action = 0;
                    serverTime = changeMatcher.group(1);
                    newOwnerSteamID = changeMatcher.group(2);
                    newOwnerPlayerName = changeMatcher.group(4);
                    oldOwnerSteamID = changeMatcher.group(5);
                    oldOwnerPlayerName = changeMatcher.group(7);
                    flagId = changeMatcher.group(8);
                    coordinateX = changeMatcher.group(9);
                    coordinateY = changeMatcher.group(10);
                    coordinateZ = changeMatcher.group(11);

                    locationX = coordinateX;
                    locationY = coordinateY;
                    locationZ = coordinateZ;
                } else if (createOrDestroyedMatcher.find()) {
                    serverTime = createOrDestroyedMatcher.group(1);
                    if (createOrDestroyedMatcher.group(2).equalsIgnoreCase("created")) {
                        action = 1;
                    } else {
                        action = 2;
                    }
                    flagId = createOrDestroyedMatcher.group(3);
                    newOwnerSteamID = createOrDestroyedMatcher.group(4);
                    newOwnerPlayerName = createOrDestroyedMatcher.group(6);
                    coordinateX = createOrDestroyedMatcher.group(7);
                    coordinateY = createOrDestroyedMatcher.group(8);
                    coordinateZ = createOrDestroyedMatcher.group(9);

                } else if (abandonedMatcher.find()) {
                    action = 4;
                    serverTime = abandonedMatcher.group(1);
                    newOwnerSteamID = abandonedMatcher.group(4);
                    newOwnerPlayerName = abandonedMatcher.group(2);
                    if (!abandonedMatcher.group(5).equalsIgnoreCase("NULL")) {
                        oldOwnerSteamID = abandonedMatcher.group(5);
                        oldOwnerPlayerName = abandonedMatcher.group(7);
                    }
                    flagId = abandonedMatcher.group(8);
                    coordinateX = abandonedMatcher.group(9);
                    coordinateY = abandonedMatcher.group(10);
                    coordinateZ = abandonedMatcher.group(11);
                    locationX = coordinateX;
                    locationY = coordinateY;
                    locationZ = coordinateZ;
                }else if (abandonedMatcher2.find()) {
                    action = 4;
                    serverTime = abandonedMatcher2.group(1);
                    newOwnerSteamID = abandonedMatcher2.group(2);
                    newOwnerPlayerName = abandonedMatcher2.group(4);
                    if (!abandonedMatcher2.group(5).equalsIgnoreCase("NULL")) {
                        oldOwnerSteamID = abandonedMatcher2.group(5);
                        oldOwnerPlayerName = abandonedMatcher2.group(7);
                    }
                    flagId = abandonedMatcher2.group(8);
                    coordinateX = abandonedMatcher2.group(9);
                    coordinateY = abandonedMatcher2.group(10);
                    coordinateZ = abandonedMatcher2.group(11);
                    locationX = coordinateX;
                    locationY = coordinateY;
                    locationZ = coordinateZ;
                }else if (abandonedMatcher3.find()) {
                    action = 4;
                    serverTime = abandonedMatcher3.group(1);
                    newOwnerSteamID = abandonedMatcher3.group(4);
                    newOwnerPlayerName = abandonedMatcher3.group(2);
                    if (!abandonedMatcher3.group(5).equalsIgnoreCase("NULL")) {
                        oldOwnerSteamID = abandonedMatcher3.group(5);
                        oldOwnerPlayerName = abandonedMatcher3.group(7);
                    }
                    flagId = abandonedMatcher3.group(8);
                    coordinateX = abandonedMatcher3.group(9);
                    coordinateY = abandonedMatcher3.group(10);
                    coordinateZ = abandonedMatcher3.group(11);
                    locationX = coordinateX;
                    locationY = coordinateY;
                    locationZ = coordinateZ;


                } else if (overtakeStartedMatcher.find()) {
                    action = 5;
                    serverTime = overtakeStartedMatcher.group(1);
                    newOwnerPlayerName = overtakeStartedMatcher.group(2);
                    newOwnerSteamID = overtakeStartedMatcher.group(4);
                    locationX = overtakeStartedMatcher.group(5);
                    locationY = overtakeStartedMatcher.group(6);
                    locationZ = overtakeStartedMatcher.group(7);
                    String ownerInfo = overtakeStartedMatcher.group(8);
                    flagId = overtakeStartedMatcher.group(9);
                    coordinateX = overtakeStartedMatcher.group(10);
                    coordinateY = overtakeStartedMatcher.group(11);
                    coordinateZ = overtakeStartedMatcher.group(12);

                    if (!ownerInfo.equals("N/A")) {
                        String[] ownerInfoParts = ownerInfo.split(", ");
                        oldOwnerSteamID = ownerInfoParts[0].substring(0, ownerInfoParts[0].indexOf('('));
                        oldOwnerPlayerName = ownerInfoParts[1].substring(0, ownerInfoParts[1].indexOf(')'));
                    }
                }else if (overtakeStartedMatcher2.find()) {
                    action = 5;
                    serverTime = overtakeStartedMatcher2.group(1);
                    newOwnerPlayerName = overtakeStartedMatcher2.group(2);
                    newOwnerSteamID = overtakeStartedMatcher2.group(4);
                    locationX = overtakeStartedMatcher2.group(5);
                    locationY = overtakeStartedMatcher2.group(6);
                    locationZ = overtakeStartedMatcher2.group(7);
                    String ownerInfo = overtakeStartedMatcher2.group(8);
                    flagId = overtakeStartedMatcher2.group(11);
                    coordinateX = overtakeStartedMatcher2.group(12);
                    coordinateY = overtakeStartedMatcher2.group(13);
                    coordinateZ = overtakeStartedMatcher2.group(14);
                    if (!ownerInfo.equalsIgnoreCase("null")) {
                        oldOwnerSteamID = overtakeStartedMatcher2.group(8);
                        oldOwnerPlayerName = overtakeStartedMatcher2.group(10);
                    }
                } else if (overtakeSuccessMatcher.find()) {
                    action = 6;
                    serverTime = overtakeSuccessMatcher.group(1);
                    newOwnerSteamID = overtakeSuccessMatcher.group(2);
                    newOwnerPlayerName = overtakeSuccessMatcher.group(4);
                    if (!overtakeSuccessMatcher.group(5).equalsIgnoreCase("null")) {
                        oldOwnerSteamID = overtakeSuccessMatcher.group(5);
                        oldOwnerPlayerName = overtakeSuccessMatcher.group(7);
                    }
                    flagId = overtakeSuccessMatcher.group(8);
                    locationX = overtakeSuccessMatcher.group(9);
                    locationY = overtakeSuccessMatcher.group(10);
                    locationZ = overtakeSuccessMatcher.group(11);
                } else if (overtakeSuccessMatcher2.find()) {
                    action = 6;
                    serverTime = overtakeSuccessMatcher2.group(1);
                    newOwnerSteamID = overtakeSuccessMatcher2.group(2);
                    newOwnerPlayerName = overtakeSuccessMatcher2.group(4);
                    if (!overtakeSuccessMatcher2.group(5).equalsIgnoreCase("null")) {
                        oldOwnerSteamID = overtakeSuccessMatcher2.group(5);
                        oldOwnerPlayerName = overtakeSuccessMatcher2.group(7);
                    }
                    flagId = overtakeSuccessMatcher2.group(8);
                    locationX = overtakeSuccessMatcher2.group(9);
                    locationY = overtakeSuccessMatcher2.group(10);
                    locationZ = overtakeSuccessMatcher2.group(11);
                } else {
                    gameplayLogConsumer.commitDiscardLog(ftpQueueItem, line, "flag no match");
                    continue;
                }

                ServerFTPLogFlag logFlag = new ServerFTPLogFlag();

                logFlag.setId(snowflakeIdGenerator.nextId());
                logFlag.setFileId(ftpQueueItem.getFileId());
                logFlag.setServerId(ftpQueueItem.getServer().getId());
                logFlag.setLineStart(line.getStartByte());
                logFlag.setLineEnd(line.getEndByte());
                logFlag.setCreateTime(LocalDateTime.now());

                logFlag.setServerTime(gameplayLogConsumer.parseTimestamp(serverTime, ftpQueueItem));
                logFlag.setType(action);
                logFlag.setFlagId(Long.parseLong(flagId));
                if (!newOwnerSteamID.isBlank()) {
                    try {
                        logFlag.setNewOwnerSteamId(Long.parseLong(newOwnerSteamID));
                        Player newOwnerPlayer = gameplayLogConsumer.getOrInsertPlayerServer(logFlag.getNewOwnerSteamId(), logFlag.getServerId(), newOwnerPlayerName);
                        logFlag.setNewOwnerPlayerId(newOwnerPlayer.getId());
                    } catch (Exception ignored) {
                    }
                }
                if (!oldOwnerSteamID.isBlank()) {
                    try {
                        logFlag.setOldOwnerSteamId(Long.parseLong(oldOwnerSteamID));
                        Player oldOwnerPlayer = gameplayLogConsumer.getOrInsertPlayerServer(logFlag.getOldOwnerSteamId(), logFlag.getServerId(), oldOwnerPlayerName);
                        logFlag.setOldOwnerPlayerId(oldOwnerPlayer.getId());
                    } catch (Exception ignored) {
                    }
                }
                if (!coordinateX.isBlank()) {
                    logFlag.setOldOwnerLocation(coordinateX + "," + coordinateY + "," + coordinateZ);
                    logFlag.setLocationZone(gameMapZoneUtil.getZone(Double.parseDouble(coordinateX), Double.parseDouble(coordinateY)));
                }
                if (!locationX.isBlank()) {
                    logFlag.setNewOwnerLocation(locationX + "," + locationY + "," + locationZ);
                    logFlag.setLocationZone(gameMapZoneUtil.getZone(Double.parseDouble(locationX), Double.parseDouble(locationY)));
                }
                flags.add(logFlag);
            }
            flags.forEach(serverFTPLogFlagMapper::insert);

            List<PlayerAlarm> alarms = Lists.newArrayList();
            if (getCurrentAlarmConfig(ftpQueueItem).getFlagEnabled()) {
                List<Long> hasAlarmPackagePlayerIds = getHasAlarmPackagePlayerIds(ftpQueueItem);
                if (!hasAlarmPackagePlayerIds.isEmpty()) {
                    flags.stream().filter(item -> hasAlarmPackagePlayerIds.contains(item.getOldOwnerPlayerId()) && (item.getType() == 5 || item.getType() == 6)).forEach(item -> {
                        PlayerAlarm playerAlarm = new PlayerAlarm();
                        playerAlarm.setServerId(item.getServerId());
                        playerAlarm.setPlayerId(item.getOldOwnerPlayerId());
                        playerAlarm.setDetail("flag table");
                        playerAlarm.setLogId(item.getId());
                        playerAlarm.setLogTime(item.getServerTime());
                        playerAlarm.setServerName(ftpQueueItem.getServer().getName());
                        playerAlarm.setAlarmDetail(item.getType() == 5 ? "开始占领" : "已被占领");
                        playerAlarm.setAlarmItem(item.getLocationZone() + "-领地棋");
                        alarms.add(playerAlarm);
                    });
                }
            }
            commitAlarmTask(alarms);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

}
